package com.tang.trap.sender;

import com.tang.constants.UserConstants;
import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;

import java.io.IOException;

/**
 * 本类用于发送Trap信息
 *
 * @author tangfl
 */
public class SnmpTrapSender {

    private Snmp snmp = null;

    private Address targetAddress = null;

    private TransportMapping<UdpAddress> transport = null;


    public static void main(String[] args) {

        SnmpTrapSender poc = new SnmpTrapSender();

        try {
            poc.init();

            /*poc.sendV1Trap();

            poc.sendV2cTrap();*/

            poc.sendV3Trap();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void init() throws IOException {
        //目标主机的ip地址 和 端口号
        targetAddress = GenericAddress.parse("udp:127.0.0.1/162");
        transport = new DefaultUdpTransportMapping();
        snmp = new Snmp(transport);
        transport.listen();
    }


    public ResponseEvent sendV1Trap() throws IOException {
        PDUv1 pdu = new PDUv1();
        VariableBinding v = new VariableBinding();
        v.setOid(SnmpConstants.sysName);
        v.setVariable(new OctetString("SnmpV1 Trap  Test"));
        pdu.add(v);
        pdu.setType(PDU.V1TRAP);

        // set target
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));
        target.setAddress(targetAddress);
        // retry times when commuication error
        target.setRetries(2);
        // timeout
        target.setTimeout(1500);
        target.setVersion(SnmpConstants.version1);
        // send pdu, return response
        return snmp.send(pdu, target);
    }

    public ResponseEvent sendV2cTrap() throws IOException {

        PDU pdu = new PDU();
        VariableBinding v = new VariableBinding();
        v.setOid(SnmpConstants.sysName);
        v.setVariable(new OctetString("SnmpV2 Trap"));
        pdu.add(v);
        pdu.setType(PDU.TRAP);

        // set target
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));
        target.setAddress(targetAddress);

        // retry times when commuication error
        target.setRetries(2);
        target.setTimeout(1500);
        target.setVersion(SnmpConstants.version2c);
        // send pdu, return response
        return snmp.send(pdu, target);

    }

    public ResponseEvent sendV3Trap() throws IOException {
        ScopedPDU pdu = new ScopedPDU();
        pdu.setType(PDU.TRAP);

        // set target
        UserTarget target = new UserTarget();
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
       
        target.setSecurityName(new OctetString(UserConstants.USERNAME));
        target.setAddress(targetAddress);
        target.setRetries(2);
        target.setTimeout(1500);
        target.setVersion(SnmpConstants.version3);

        // Add variables to your trap
        VariableBinding v = new VariableBinding();
        v.setOid(SnmpConstants.sysName);
        v.setVariable(new OctetString("SnmpV3 Trap"));
        pdu.add(v);

        // Specify the security settings
        SecurityProtocols.getInstance().addDefaultProtocols();
        SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES128());
        USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
        SecurityModels.getInstance().addSecurityModel(usm);

        // Add user with security settings
        snmp.getUSM().addUser(new OctetString(UserConstants.USERNAME), new UsmUser(new OctetString(UserConstants.USERNAME),
                AuthSHA.ID, new OctetString(UserConstants.AUTH_PASSWORD), PrivAES128.ID, new OctetString(UserConstants.PRIV_PASSWORD)));

        // Send pdu, return response
        return snmp.send(pdu, target);
    }
    

}
